<html>
 <head>
  <script language="javascript" src="../core/bootFOAM.js"></script>
  <title>Predictive Touch</title>
 </head>
 <body bgcolor='black'>
  <script language="javascript">
    var space   = Canvas.create({width: 2000, height: 1700, background:'black'});
    var mouse   = Mouse.create();
       var c1 = Circle.create({
         r: 35,
         color: 'black',
         borderWidth: 25,
         border: 'white'
       });
       var c2 = Circle.create({
         r: 35,
         color: 'black',
         borderWidth: 25,
         border: 'blue'
       });

    space.write(document);
    space.addChild(c1);
    space.addChild(c2);
    mouse.connect(space.$);

    function ema() {
       var avg = undefined;
       return function(x) {
         if ( avg == undefined ) {
            avg = x;
         } else if ( Math.abs(x-avg) > 15 ) {
            avg = x;
         } /*else if ( ( avg > 0 ) != ( x > 0 ) ) {
            avg = x;
         } */ else {
            avg = ( 5 * avg + x ) / 6;
         }
         return avg;
       };
    }

    var p = function(future) {
      var SIZE = 8;
      var h = [];
      var avg = ema();

      return function(v, ts) {
        if ( h.length && ts-h[0][1] > 25 ) h = [];
        if ( h.length > 1 && ( v-h[0][0] > 0 ) != ( v-h[1][0] > 0 ) ) h = [];
        h.unshift([v,ts]);
        if ( h.length < SIZE ) return v;
        if ( h.length > SIZE ) h.pop();
        var d = 0;
        var t = 0;
        for ( var i = 1 ; i < SIZE ; i++ ) {
          d += v-h[i][0];
          t += ts-h[i][1];
        }
        var s = d / t;
        return v+avg(s)*future;
      };
    };

    function predictor(f) {
       var xAvg = ema();
       var yAvg = ema();
       var xP = p(16*8);
       var yP = p(16*8);
       return function(x, y, ts) {
         return f(xAvg(xP(x, ts)), yAvg(yP(y, ts)), ts);
       };
    }

    function handleTouch(c) { return function(x, y, ts) {
       c.x = x; c.y = y;
    }};

    var f1 = handleTouch(c1);
    var f2 = predictor(handleTouch(c2));

    space.$.addEventListener('touchmove', function(e) {
       // console.log(e);
       e.preventDefault();
       var x = e.changedTouches[0].pageX;
       var y = e.changedTouches[0].pageY;

       f1(x, y, e.timeStamp);
       f2(x, y, e.timeStamp);
    }, true);
  </script>
 </body>
</html>
